﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Utils;
using System.Linq;
using System.Collections.Generic;

namespace Hydra.Shell.DelayObjects
{
    [AttributeUsage(AttributeTargets.Field)]
    public class TypeDescriptionFormatAttribute : Attribute
    {
        public string DescriptionFormatText { get; private set; }
        public string[] TypeParams { get; private set; }

        public TypeDescriptionFormatAttribute(string descriptionFormatText, params string[] typeParams)
        {
            this.DescriptionFormatText = descriptionFormatText;
            this.TypeParams = typeParams;
        }
    }

    public static class ReportHistoryDescription
    {
        public static string GetDescription(this ReportHistoryType type, object[] parms)
        {
            var formatAttr = typeof(ReportHistoryType).GetCustomAttribute<TypeDescriptionFormatAttribute>(type);

            return string.Format(formatAttr.DescriptionFormatText, parms);
        }

        public static bool HasTimeout(this ReportHistoryType type)
        {
            var formatAttr = typeof(ReportHistoryType).GetCustomAttribute<TypeDescriptionFormatAttribute>(type);
            var hasTimeoutParm = formatAttr.TypeParams.Any(p => p.StartsWith("TimeSpan "));

            return hasTimeoutParm;
        }

        public static TimeSpan GetTimeout(this ReportHistoryType type, object[] parms)
        {
            var formatAttr = typeof(ReportHistoryType).GetCustomAttribute<TypeDescriptionFormatAttribute>(type);
            var index = formatAttr.TypeParams.IndexOf(p => p.StartsWith("TimeSpan "));

            return (TimeSpan) parms[index];
        }
    }

    public enum ReportHistoryType
    {
        /// <summary>
        /// params: string serviceName
        /// </summary>
        /// <typeparam name="serviceName" />
        [TypeDescriptionFormat("Attempting to get service {0}", "string serviceName")]
        AttemptingToGetService,

        /// <summary>
        /// params: string serviceName
        /// </summary>
        /// <typeparam name="serviceName" />
        [TypeDescriptionFormat("Service {0} returned successfully", "string serviceName")]
        ServiceReturnedSuccessfully,

        /// <summary>
        /// params: serviceName
        /// </summary>
        /// <typeparam name="serviceName" />
        [TypeDescriptionFormat("Querying for service {0}", "string serviceName")]
        QueryingForService,

        /// <summary>
        /// params: string serviceName, TimeSpan timeOut
        /// </summary>
        /// <typeparam name="serviceName" />
        /// <typeparam name="timeOut" />
        [TypeDescriptionFormat("Querying for service {0}", "string serviceName", "TimeSpan timeOut")]
        QueryingForServiceWithTimeout,

        /// <summary>
        /// params: string serviceName, bool returnValue
        /// </summary>
        /// <typeparam name="serviceName" />
        /// <typeparam name="returnValue" />
        [TypeDescriptionFormat("Query for service {0} returned {1}", "string serviceName", "bool returnValue")]
        QueryRequestReturned,

        /// <summary>
        /// params: string serviceName
        /// </summary>
        /// <typeparam name="serviceName" />
        [TypeDescriptionFormat("Service {0} loaded successfully", "string serviceName")]
        ServiceLoadedSuccessfully,

        /// <summary>
        /// params: string serviceName, string nextStep
        /// </summary>
        /// <typeparam name="serviceName" />
        /// <typeparam name="timeOut" />
        [TypeDescriptionFormat("Service {0} loaded successfully, continuing to {1}", "string serviceName", "string nextStep")]
        ServiceLoadedSuccessfullyContinue,

        /// <summary>
        /// params: string functionName
        /// </summary>
        [TypeDescriptionFormat("Calling '{0}'", "string functionName")]
        CallingFunction,

        /// <summary>
        /// params: string functionName
        /// </summary>
        [TypeDescriptionFormat("'{0}' returned successfully", "string functionName")]
        CallingFunctionReturnSuccessfully,

        /// <summary>
        /// params: string fileName
        /// </summary>
        [TypeDescriptionFormat("Opening '{0}'", "string fileName")]
        OpeningFile
    }
}
